package IMDBQuery;

import UserProfile.Configuration;
import UserProfile.MovieMap;

import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;

/**
 * Clase que gestiona todo lo referente al establecimiento de atributos a las
 * peliculas consultando las bases de IMDB.
 *
 */
public class IMDBReader {

    /**
     * Obtiene las caracteristicas semanticas de una pelicula, buscandolas en la
     * base de IMDb
     *
     * @param movieLine informacion de la pelicula obtenida de la BD MovieLens
     * @param conf configuracion del sistema
     * @return pelicula cargada con caracteristicas semanticas segun IMDb
     */
    public static MovieIMDB getMovieIMDB(String movieLine, Configuration conf) {

        MovieIMDB movie = null;

        try {
            FileWriter f1 = new FileWriter(conf.getOUTMOVIESNOTFOUND(), true);
            BufferedWriter b1 = new BufferedWriter(f1);

            String campos[] = movieLine.split("::");

            movie = new MovieIMDB(campos[2]);
            if (MovieMap.getInstance().getMapaPeliculas().containsKey(campos[1])) {
              //  System.err.println("de memoria");
                return MovieMap.getInstance().getMapaPeliculas().get(campos[1]);
            } else {
                //Busco el Identificador de la pelicula
                String json = getIdApiIMDB(campos[1]);

                try {
                    movie.setID(campos[1]);

                    movie.setLineInDAT(movieLine);

                    String generos[] = JsonParser.parse(json, "Genre").split(",");
                    for (int genero = 0; genero < generos.length; genero++) {
                        if (!generos[genero].equals("N/A")) {
                            movie.addGenre(generos[genero]);
                        }
                    }

                    String actores[] = JsonParser.parse(json, "Actors").split(",");
                    for (int actor = 0; actor < actores.length; actor++) {
                        if (!actores[actor].equals("N/A")) {
                            movie.addCast(actores[actor]);
                        }
                    }

                    String directores[] = JsonParser.parse(json, "Director").split(",");
                    for (int director = 0; director < directores.length; director++) {
                        if (!directores[director].equals("N/A")) {
                            movie.addDirector(directores[director]);
                        }
                    }

                    String escritores[] = JsonParser.parse(json, "Writer").split(",");
                    if(escritores.length>3)
                        escritores= new String[]{escritores[0], escritores[1], escritores[2]};
                    for (int escritor = 0; escritor < escritores.length; escritor++) {
                        if (!escritores[escritor].equals("N/A")) {
                            movie.addWriter(escritores[escritor]);
                        }
                    }

                    String rating = JsonParser.parse(json, "imdbRating");
                    String votes = JsonParser.parse(json, "imdbVotes");
                    movie.setRating(votes, rating);

                } catch (Exception e) {
                    b1.write(movieLine);
                    b1.newLine();
                    b1.flush();
                    System.out.println("\tID Not Found! Network Connection Failed! " + e.getMessage());
                    movie = null;
                }
                MovieMap.getInstance().getMapaPeliculas().put(campos[1], movie);
                return movie;
            }
        } catch (NullPointerException e) {
            System.out.println("ReadMovies() Error: " + e.getMessage() + movieLine);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * Abre una conexion a la pagina web http://www.omdbapi.com/ con el fin de
     * obtener el identificador IMDB de la pelicula <code>title</code>, la cual
     * fue estrenada en el anio <code>year</code>.
     *
     * @param title Titulo de la pelicula
     * @param year Anio de estreno de la pelicula
     * @return cadena json con los datos de la pelicula
     */
    @SuppressWarnings("ConvertToTryWithResources")
    public static String getIdApiIMDB(String title, String year) {

        String linea, encodeTitle = null;
        String jsonTxt = null;
        try {
            encodeTitle = URLEncoder.encode(title, "UTF-8");
            URL url = new URL("http://www.omdbapi.com/?t=" + encodeTitle + "&y=" + year);
            URLConnection uc = url.openConnection();
            InputStream stream = uc.getInputStream();
            BufferedReader br = new BufferedReader(new InputStreamReader(stream));

            while ((linea = br.readLine()) != null) {
                jsonTxt = linea;
            }
            br.close();
        } catch (IOException e) {
            System.out.println("GetIdApiIMDB() Error: " + e.getMessage());
        }
        return jsonTxt;
    }

    /**
     * Abre una conexion a la pagina web http://www.omdbapi.com/ con el fin de
     * obtener el identificador IMDB de la pelicula <code>title</code>, la cual
     * fue estrenada en el anio <code>year</code>.
     *
     * @param id identificador IMDb de la pelicula
     * @return cadena json con los datos de la pelicula
     */
    @SuppressWarnings("ConvertToTryWithResources")
    public static String getIdApiIMDB(String id) {

        String linea = null;
        String jsonTxt = null;
        try {
            URL url = new URL("http://www.omdbapi.com/?i=" + id);
            URLConnection uc = url.openConnection();
            InputStream stream = uc.getInputStream();
            BufferedReader br = new BufferedReader(new InputStreamReader(stream));

            while ((linea = br.readLine()) != null) {
                jsonTxt = linea;
            }
            br.close();

        } catch (IOException e) {
            System.out.println("GetIdApiIMDB() Error: " + e.getMessage());
        }
        return jsonTxt;
    }

}
